package com.danceforyou.payment.service.impl;

import com.danceforyou.common.restful.exception.BizExceptionEnum;
import com.danceforyou.common.service.OperationService;
import com.danceforyou.common.service.impl.BaseServiceImpl;
import com.danceforyou.common.util.AssertUtil;
import com.danceforyou.common.util.Constants;
import com.danceforyou.medium.model.MediumDO;
import com.danceforyou.medium.service.MediumService;
import com.danceforyou.order.model.OrderDO;
import com.danceforyou.order.service.OrderService;
import com.danceforyou.ossFile.model.OssFileDO;
import com.danceforyou.ossFile.service.OssFileService;
import com.danceforyou.payment.dao.PaymentDAO;
import com.danceforyou.payment.model.PaymentDO;
import com.danceforyou.payment.model.PaymentVoucherDO;
import com.danceforyou.payment.service.PaymentService;
import com.danceforyou.payment.service.PaymentVoucherService;
import com.danceforyou.payment.vo.PaymentVO;
import com.danceforyou.user.vo.UserVO;
import com.danceforyou.websocket.BacklogSocket;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 类名称：PaymentServiceImpl
* 创建人：danceforyou
* 创建时间：2021年02月05日
* 版本号：1.0v
*/
@Service("paymentService")
public class PaymentServiceImpl extends BaseServiceImpl<Long, PaymentDO, PaymentVO, PaymentDAO> implements PaymentService {
    @Autowired
    private PaymentDAO paymentDAO;
    @Autowired
    private OrderService orderService;
    @Autowired
    private MediumService mediumService;
    @Autowired
    private OssFileService ossFileService;
    @Autowired
    private PaymentVoucherService paymentVoucherService;
    @Autowired
    private OperationService operationService;
    @Autowired(required = false)
    private HttpSession session;

    @Override
    public PaymentDAO getDao() {
        return paymentDAO;
    }

    @Override
    public void saveInfo(PaymentDO payment) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        //查询排期信息
        OrderDO order = orderService.getById(payment.getOrderId());
        AssertUtil.notNull(order, "排期信息不存在，操作失败");
        AssertUtil.isTrue(!order.getIsPayment(), "该排期已完成付款，请勿重复发起");
        //查询排期已付款金额（待审核、审核通过、已支付）
        BigDecimal payedMoney = this.sumByCondition("payMoney", new HashMap<String, Object>(){{
            put("orderId", payment.getOrderId());
            put("statusList", new int[]{Constants.PAYMENT_STATUS_FILLIN, Constants.PAYMENT_STATUS_PASSED, Constants.PAYMENT_STATUS_FINISH});
            put("isDelete", false);
        }});
        BigDecimal repayMoney = order.getCostPrice().subtract(payedMoney);
        AssertUtil.isTrue(payment.getPayMoney().compareTo(repayMoney) <= 0, "总付款金额不能大于排期成本价");
        payment.setCreateUserId(loginUser.getId());
        payment.setCreateDate(new Date());
        payment.setStatus(Constants.PAYMENT_STATUS_FILLIN);
        payment.setIsDelete(false);
        this.insert(payment);
        operationService.saveOperation(Constants.OPER_TABLE_PAYMENT, payment.getId(), Constants.OPER_ADD, loginUser, null);
        //发送待办消息
        BacklogSocket.sendBacklogMessage(Constants.MENU_BACKLOG_PAYMENT_AUDIT);
    }

    @Override
    public void updateInfo(PaymentDO payment) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        PaymentDO temp = this.getById(payment.getId());
        AssertUtil.notNull(temp, "信息不存在");
        AssertUtil.isTrue(temp.getStatus() == Constants.PAYMENT_STATUS_FILLIN || temp.getStatus() == Constants.PAYMENT_STATUS_NOPASS, "该申请已审核通过，无法修改");
        //查询排期信息
        OrderDO order = orderService.getById(payment.getOrderId());
        AssertUtil.notNull(order, "排期信息不存在，操作失败");
        //查询排期已付款金额（待审核、审核通过、已支付）
        BigDecimal payedMoney = this.sumByCondition("payMoney", new HashMap<String, Object>(){{
            put("orderId", payment.getOrderId());
            put("statusList", new int[]{Constants.PAYMENT_STATUS_FILLIN, Constants.PAYMENT_STATUS_PASSED, Constants.PAYMENT_STATUS_FINISH});
            put("isDelete", false);
        }});
        BigDecimal repay_money = order.getCostPrice().subtract(payedMoney).add(temp.getPayMoney());
        AssertUtil.isTrue(payment.getPayMoney().compareTo(repay_money) <= 0, "总付款金额不能大于排期成本价");
        payment.setStatus(Constants.PAYMENT_STATUS_FILLIN);
        payment.setIsDelete(false);
        this.update(payment);
        operationService.saveOperation(Constants.OPER_TABLE_PAYMENT, payment.getId(), Constants.OPER_EDIT, loginUser, null);
        //发送待办消息
        BacklogSocket.sendBacklogMessage(Constants.MENU_BACKLOG_PAYMENT_AUDIT);
    }

    @Override
    public int deleteInfoByIds(String ids) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        String[] idArr = ids.split(",");
        int i = 0;
        for (String id : idArr) {
            PaymentDO payment = this.getById(Long.valueOf(id));
            AssertUtil.notNull(payment, "信息不存在");
            AssertUtil.isTrue(payment.getStatus() == Constants.PAYMENT_STATUS_FILLIN || payment.getStatus() == Constants.PAYMENT_STATUS_NOPASS, "该申请已审核通过，无法删除");
            i += this.setDelete(payment);
            operationService.saveOperation(Constants.OPER_TABLE_PAYMENT, payment.getId(), Constants.OPER_DELETE, loginUser, null);
        }
        //发送待办消息
        BacklogSocket.sendBacklogMessage(Constants.MENU_BACKLOG_PAYMENT_AUDIT);
        return i;
    }

    @Override
    public int setPaymentAuditPass(String ids) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        String[] idArr = ids.split(",");
        int i = 0;
        for (String id : idArr) {
            PaymentDO payment = this.getById(Long.valueOf(id));
            AssertUtil.notNull(payment, "信息不存在");
            AssertUtil.isTrue(payment.getStatus() == Constants.PAYMENT_STATUS_FILLIN || payment.getStatus() == Constants.PAYMENT_STATUS_NOPASS, "非待审核状态");
            payment.setStatus(Constants.PAYMENT_STATUS_PASSED);
            payment.setAuditUserId(loginUser.getId());
            payment.setAuditDate(new Date());
            i += this.update(payment);
            //记录操作日志
            operationService.saveOperation(Constants.OPER_TABLE_PAYMENT, payment.getId(), Constants.OPER_PASSED, loginUser, null);
        }
        //发送待办消息
        BacklogSocket.sendBacklogMessage(Constants.MENU_BACKLOG_PAYMENT_AUDIT);
        BacklogSocket.sendBacklogMessage(Constants.MENU_BACKLOG_PAYMENT_PAY);
        return i;
    }

    @Override
    public int setPaymentAuditNoPass(String ids, String auditDesc) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        String[] idArr = ids.split(",");
        int i = 0;
        for (String id : idArr) {
            PaymentDO payment = this.getById(Long.valueOf(id));
            AssertUtil.notNull(payment, "信息不存在");
            AssertUtil.isTrue(payment.getStatus() == Constants.PAYMENT_STATUS_FILLIN || payment.getStatus() == Constants.PAYMENT_STATUS_PASSED, "非待审核状态");
            payment.setStatus(Constants.PAYMENT_STATUS_NOPASS);
            payment.setAuditUserId(loginUser.getId());
            payment.setAuditDate(new Date());
            payment.setAuditDesc(auditDesc);
            i += this.update(payment);
            //记录操作日志
            operationService.saveOperation(Constants.OPER_TABLE_PAYMENT, payment.getId(), Constants.OPER_NOPASS, loginUser, null);
        }
        //发送待办消息
        BacklogSocket.sendBacklogMessage(Constants.MENU_BACKLOG_PAYMENT_AUDIT);
        BacklogSocket.sendBacklogMessage(Constants.MENU_BACKLOG_PAYMENT_PAY);
        return i;
    }

    @Override
    public int setPaymentPayed(MultipartFile[] fileList, String ids) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        String[] idArr = ids.split(",");
        int i = 0;
        for (String id : idArr) {
            PaymentDO payment = this.getById(Long.valueOf(id));
            AssertUtil.notNull(payment, "信息不存在");
            AssertUtil.isTrue(payment.getStatus() == Constants.PAYMENT_STATUS_PASSED || payment.getStatus() == Constants.PAYMENT_STATUS_FINISH, "非待支付状态");
            OrderDO order = orderService.getById(payment.getOrderId());
            AssertUtil.notNull(order, "排期信息不存在，非法操作");
            payment.setStatus(Constants.PAYMENT_STATUS_FINISH);
            payment.setPayUserId(loginUser.getId());
            payment.setPayDate(new Date());
            i += this.update(payment);
            //更改排期付款状态
            BigDecimal payedMoney = this.sumByCondition("payMoney", new HashMap<String, Object>(){{
                put("orderId", payment.getOrderId());
                put("status", Constants.PAYMENT_STATUS_FINISH);
                put("isDelete", false);
            }});
            if (payedMoney.compareTo(order.getCostPrice()) >= 0) {
                order.setIsPayment(true);
                orderService.update(order);
            }
            //删除原有的附件
            paymentVoucherService.deleteByProperty("paymentId", payment.getId());
            //上传新的附件
            for (MultipartFile file : fileList) {
                OssFileDO ossFile = ossFileService.saveInfo(file);
                PaymentVoucherDO voucher = new PaymentVoucherDO();
                voucher.setPaymentId(payment.getId());
                voucher.setOssFileId(ossFile.getId());
                paymentVoucherService.insert(voucher);
            }
            //将付款信息回写至公众号信息中
            MediumDO medium = mediumService.getById(order.getMediumId());
            AssertUtil.notNull(medium, "公众号信息不存在，非法操作");
            medium.setRecName(payment.getRecName());
            medium.setRecAccount(payment.getRecAccount());
            medium.setRecBank(payment.getRecBank());
            mediumService.update(medium);
            //记录操作日志
            operationService.saveOperation(Constants.OPER_TABLE_PAYMENT, payment.getId(), Constants.OPER_PAY, loginUser, null);
        }
        //发送待办消息
        BacklogSocket.sendBacklogMessage(Constants.MENU_BACKLOG_PAYMENT_PAY);
        return i;
    }

    @Override
    public Map statPaymentInfo(String roleType, Long userId) {
        return paymentDAO.statPaymentInfo(roleType, userId);
    }
}
